using System;
using System.Collections.Generic;

using Gtk;
using Cairo;

using stefc.geo.lib;
using stefc.geo.data;
using stefc.geo.data.model;

using MyLocate.util;
using MyLocate.dlg;

namespace MyLocate {

public partial class MainWindow : Gtk.Window
{
	private bool isMetric;
	private double angle;
	private List<ContactPin> contacts;
	private Geographic myLocation;
	private Tooltips tooltips;
		
	public MainWindow () : base(Gtk.WindowType.Toplevel)
	{
		Build ();
			
		this.isMetric = Configuration.Instance.IsMetric;
		this.angle = MathUtil.ToRadiant(0);  // the north
		this.myLocation = new Geographic("52°31' 13°22'");  // berlin 
			
		this.contacts = new List<MainWindow.ContactPin>();
		this.contacts.Add(new ContactPin(new Geographic(53.865486,10.252647), "Leezen",ColorMapFactory.White));
		this.contacts.Add(new ContactPin(new Geographic(53.682,10.009), "Ochsenzoll",ColorMapFactory.Green));
		this.contacts.Add(new ContactPin(new Geographic("59°54' 10°44'"), "Oslo",ColorMapFactory.Black));
		this.contacts.Add(new ContactPin(new Geographic("40°44' -74°02'"), "New York",ColorMapFactory.LightCoral));
		this.contacts.Add(new ContactPin(new Geographic("40°25' -3°42'"),"Madrid", ColorMapFactory.Green));
		this.contacts.Add(new ContactPin(new Geographic("35°40' 139°35'"),"Tokio", ColorMapFactory.Red));
        this.contacts.Add(new ContactPin(new Geographic(55.75, 37.616667),"Moskau", ColorMapFactory.RoyalBlue));
        	
		this.tooltips=new Tooltips();
		
		
		DatabaseManager.Instance.SetValue<string>("Root","wurzel");
	}

	protected void OnDeleteEvent (object sender, DeleteEventArgs a)
	{
		Application.Quit ();
		a.RetVal = true;
	}
	
	protected virtual void OnButtonContactsClicked (object sender, System.EventArgs e)
	{
		ContactsDialog.Edit();
	}
		
	protected virtual void OnButtonPreferencesClicked (object sender, System.EventArgs e)
	{
		if(PreferencesDialog.Edit())
		{
			this.isMetric = Configuration.Instance.IsMetric;
				
			this.canvas.ModifyBase(StateType.Normal);
		}		
		//	this.isMetric=!this.isMetric;
		//	this.angle += MathUtil.ToRadiant(5);
		//	;
	}
		

	public void In_GPSFix(Geographic geo)
    {
		//if(geo.GetDistance(this.myLocation)>0.005)
		{
			this.myLocation=geo;
			this.canvas.ModifyBase(StateType.Normal);
		}
	}
	
	
	
	protected virtual void OnCanvasExposeEvent (object sender, Gtk.ExposeEventArgs args)
	{
		DrawingArea area = (DrawingArea) sender;
        Cairo.Context cr =  Gdk.CairoHelper.Create(area.GdkWindow);
        
		Drawing drawing = new Drawing(
			new GtkCanvas(cr,
			            area.Allocation.Width,area.Allocation.Height), 
			            this.myLocation.ToString(),
			            area.Allocation.Width,area.Allocation.Height,
			            this.isMetric, this.angle);
			
		drawing.Paint();	
			
		foreach(ContactPin contact in this.contacts)
		{
			drawing.DrawPin(
				this.myLocation.GetAngle(contact.Location),
				this.myLocation.GetDistance(contact.Location)*1000,  // km
				contact.Color);
		}

        ((IDisposable) cr.Target).Dispose();                                      
        ((IDisposable) cr).Dispose();
	}
	
	
	protected virtual void OnCanvasButtonPressEvent (object sender, Gtk.ButtonPressEventArgs args)
	{
		if(args.Event.Button==1)
		{
				DrawingArea area = (DrawingArea) sender;
				
				// translate origin of coordinate system
				int width=area.Allocation.Width;
				int height=area.Allocation.Height;
				int radius=((width < height ? width:height) / 2)-4;
			
				Cartesian coord = new Cartesian(
					args.Event.X - (width/2), args.Event.Y - (height/2));
        
				ContactPin match =  null;
				double minDistance = 9999;
				foreach(ContactPin contact in this.contacts)
				{
					Polar polar = new Polar(
						this.myLocation.GetAngle(contact.Location),
						this.myLocation.GetDistance(contact.Location)*1000);
					Cartesian cartesian = new Cartesian(
						Math.Cos(polar.Angle-(Math.PI/2))*radius*Drawing.GetFactor(polar.Distance),
			    		Math.Sin(polar.Angle-(Math.PI/2))*radius*Drawing.GetFactor(polar.Distance));
					
					
					double distance = cartesian.GetDistance(coord);
					if(distance < minDistance)
					{
						minDistance=distance;
						match = contact;
					}
					// Console.WriteLine("{0}={1},{2}", contact.Name, cartesian, polar);
				}
				
				// this.Title = String.Format("Press : {0} Radius={1}", coord, radius);
				
				if(match!=null)
				{
					this.tooltips.SetTip(this.canvas,match.Name,null);
					this.tooltips.Enable();
				}
				else
					this.tooltips.Disable();
		}
	}	
	
	protected virtual void OnCanvasMotionNotifyEvent (object sender, Gtk.MotionNotifyEventArgs args)
	{
		DrawingArea area = (DrawingArea) sender;
		
		// translate origin of coordinate system
		int width=area.Allocation.Width;
		int height=area.Allocation.Height;
		int radius=((width < height ? width:height) / 2)-4;
	
		Cartesian coord = new Cartesian(
			args.Event.X - (width/2), args.Event.Y - (height/2));

		double distance = coord.GetDistance(Cartesian.Zero);
		this.Title= String.Format("{0}-{1}", distance, radius);		
	}
	
	
	private class ContactPin 
	{
		private Geographic location;
		private string name;
		private Int32 color;
			
		public ContactPin(Geographic location, string name, Int32 color)
		{
			this.location=location;
			this.name=name;
			this.color=color;
		}
		
		public Geographic Location { get { return this.location; } }
		
		public string Name { get { return this.name; } }
			
		public Int32 Color { get { return this.color; } }
	}
}	
	
	
}
